#ifndef _Scene_H_
#define _Scene_H_

#pragma once
#include "LightingRender.h"
#include "Primitive.h"
#include "Light.h"
#include "Sampler.h"

class Camera;
class Integrator;

class Scene {
	typedef vector<shared_ptr<Primitive>> Primitives;
	typedef vector<shared_ptr<Light>> Lights;
private:
	Primitives primitives, emitters;
	Lights lights;
	shared_ptr<Camera> camera;
	shared_ptr<Integrator> integrator;
	shared_ptr<Material> backGround;
	const int transparentDepth = 3;

public:
	Scene();
	~Scene();

	void addPrimitive(shared_ptr<Primitive> p);
	void addLight(shared_ptr<Light> l);
	void setBackGround(shared_ptr<Material> backGroundMaterial);
	inline const shared_ptr<Material> & getBackGround() const {
		return backGround;
	}
	void setCamera(shared_ptr<Camera> camera);
	inline const shared_ptr<Camera> & getCamera() const {
		return camera;
	}
	void setIntegrator(shared_ptr<Integrator> integrator);
	inline const shared_ptr<Integrator> & getIntegrator() const {
		return integrator;
	}

	bool intersect(IntersectResult &result, const Ray &ray) const;
	bool intersect(IntersectResult &result, const Ray &ray, Double minDistance, Double maxDistance) const;
	bool intersectP(const Ray &ray) const;
	bool intersectP(const Ray &ray, Double minDistance, Double maxDistance) const;

	Double traceShadow(const Ray & ray, Color & shadowColor, Double maxDistance = Infinity) const;
	Color sampleLight(const Vector3 &position, const Vector3 & normal) const;
};

#endif // _Scene_H_